﻿using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http.Headers;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using Volo.Abp.Application.Dtos;
using Volo.Abp;
using System.Net.Http.Json;
using Microsoft.IdentityModel.Tokens;

namespace Himp.Platform.Apps
{
    /// <summary>
    /// 日志服务
    /// </summary>
    public class LogInfoService : LogBaseService
    {
        private IHttpClientFactory _httpClientFactory;
        //http://112.33.111.160:8088/api/v2/projects/6646c8ee29023f00163b06f8/events
        private string logUrl = "/api/v2/events";
        private string countUrl = "http://112.33.111.160:8088/api/v2/events/count?filter=(status:open+OR+status:regressed)&offset=480m&time=last+24+hours";
        private string filter = "filter=(status:open+OR+status:regressed)";
        private string offset = "&offset=480m";
        private string defaultTime = "&time=last+hour";
        private ILogger<LogInfoService> _logger;
        public const string TokenRedisKey = "exceptionless/token";

        /// <summary>
        /// , ConnectionMultiplexer redis
        /// </summary>
        /// <param name="httpClientFactory"></param>
        /// <param name="logger"></param>
        public LogInfoService(IHttpClientFactory httpClientFactory, ILogger<LogInfoService> logger) :
            base(httpClientFactory, logger)
        {
            _httpClientFactory = httpClientFactory;
            _logger = logger;
            //_redisDatabase = redis.GetDatabase();
        }

        /// <summary>
        /// 获取日志概要列表
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        /// <exception cref="AbpException"></exception>
        public async Task<PagedResultDto<EventSummaryDto>> Get(LogInput input)
        {
            _logger.LogDebug(DateTime.Now.ToString());
            string mode = "summary";
            var client = _httpClientFactory.CreateClient();
            var token = await Login();
            client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
            StringBuilder dataUrlSB = new StringBuilder();
            dataUrlSB.Append(_baseUrl);
            dataUrlSB.Append("/api/v2");

            if (!string.IsNullOrEmpty(input.ProjectId))
            {
                dataUrlSB.Append("/projects/");
                dataUrlSB.Append(input.ProjectId);
            }

            dataUrlSB.Append("/events");
            dataUrlSB.Append("?");
            dataUrlSB.Append(filter);

            if (input.ExceptionFlag)
            {
                dataUrlSB.Append("+type:error");
            }

            if (!string.IsNullOrWhiteSpace(input.Filter))
            {
                dataUrlSB.Append($"+({input.Filter})");
            }

            dataUrlSB.Append(offset);

            if (input.StartTime.HasValue && input.EndTime.HasValue)
            {
                dataUrlSB.Append($"&time={input.StartTime.Value.ToString("yyyy-MM-ddTHH:mm:ss")}-{input.EndTime.Value.ToString("yyyy-MM-ddTHH:mm:ss")}");
            }
            else
            {
                dataUrlSB.Append(defaultTime);
            }

            dataUrlSB.Append($"&mode={mode}");
            dataUrlSB.Append($"&page={input.Pi}");
            dataUrlSB.Append($"&limit={input.Ps}");
            var eventDataResponseModel = await client.GetAsync(dataUrlSB.ToString());

            StringBuilder countUrlSB = new StringBuilder();
            countUrlSB.Append(_baseUrl);
            countUrlSB.Append("/api/v2");

            if (!string.IsNullOrEmpty(input.ProjectId))
            {
                countUrlSB.Append("/projects/");
                countUrlSB.Append(input.ProjectId);
            }

            countUrlSB.Append("/events");
            countUrlSB.Append("/count?");
            countUrlSB.Append(filter);

            if (input.ExceptionFlag)
            {
                countUrlSB.Append("+type:error");
            }

            if (!string.IsNullOrWhiteSpace(input.Filter))
            {
                countUrlSB.Append($"+({input.Filter})");
            }

            countUrlSB.Append(offset);

            if (input.StartTime.HasValue && input.EndTime.HasValue)
            {
                countUrlSB.Append($"&time={input.StartTime.Value.ToString("yyyy-MM-ddTHH:mm:ss")}-{input.EndTime.Value.ToString("yyyy-MM-ddTHH:mm:ss")}");
            }
            else
            {
                countUrlSB.Append(defaultTime);
            }

            var eventCountResponseModel = await client.GetAsync(countUrlSB.ToString());

            if (eventDataResponseModel.StatusCode == System.Net.HttpStatusCode.OK
                && eventCountResponseModel.StatusCode == System.Net.HttpStatusCode.OK)
            {
                var eventSummaryModel = await eventDataResponseModel.Content.ReadFromJsonAsync<ICollection<EventSummaryDto>>();
                var eventCount = await eventCountResponseModel.Content.ReadFromJsonAsync<EventCountDto>();

                foreach (var item in eventSummaryModel.Where(e => !e.Data.ContainsKey("Level")))
                {
                    item.Data.Add("Level", "Exception");
                }
                return new PagedResultDto<EventSummaryDto>(eventCount.Total, eventSummaryModel.ToList());
            }
            else
            {
                throw new AbpException("获取日志数据失败");
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        /// <exception cref="AbpException"></exception>
        public async Task<PersistentEventDto> Get(string id)
        {
            //http://112.33.111.160:8088/api/v2/events/65f2b03d5da81e0001ff0e4d?filter=(status:open+OR+status:regressed)+stack:current&offset=480m&time=last+24+hours
            var token = await Login();
            var client = _httpClientFactory.CreateClient();
            client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
            StringBuilder dataUrlSB = new StringBuilder();
            dataUrlSB.Append(_baseUrl);
            dataUrlSB.Append("/api/v2");
            dataUrlSB.Append("/events");
            dataUrlSB.Append($"/{id}?");
            dataUrlSB.Append(filter + "+stack:current");
            dataUrlSB.Append(offset);
            dataUrlSB.Append(defaultTime);
            var eventDataResponseModel = await client.GetAsync(dataUrlSB.ToString());

            if (eventDataResponseModel.StatusCode == System.Net.HttpStatusCode.OK)
            {
                var eventDataModel = await eventDataResponseModel.Content.ReadFromJsonAsync<PersistentEventDto>();

                return eventDataModel;
            }
            else
            {
                throw new AbpException("获取日志数据失败");
            }
        }

        ///// <summary>
        ///// 
        ///// </summary>
        ///// <returns></returns>
        //private async Task<string> Login()
        //{
        //    //var token = await _redisDatabase.StringGetAsync(TokenRedisKey);

        //    //if (!token.IsNullOrEmpty)
        //    //{
        //    //    return token;
        //    //}

        //    var clinet = _httpClientFactory.CreateClient();

        //    LogLoginReq logLogin = new LogLoginReq()
        //    {
        //        Email = "1010331798@qq.com",
        //        Password = "1q2w3E*"
        //    };

        //    var content = new StringContent(Newtonsoft.Json.JsonConvert.SerializeObject(logLogin), Encoding.UTF8, "application/json");
        //    var client = _httpClientFactory.CreateClient(nameof(LogService));
        //    var responseModel = await client.PostAsync($"http://112.33.111.160:8088/api/v2/auth/login", content);

        //    if (responseModel.StatusCode == System.Net.HttpStatusCode.OK)
        //    {
        //        var logLoginRes = await responseModel.Content.ReadFromJsonAsync<LogLoginRes>();
        //        // 存储 Token 到 Redis，设置过期时间
        //        //await _redisDatabase.StringSetAsync(TokenRedisKey, token, TimeSpan.FromDays(1));

        //        return logLoginRes.Token;
        //    }
        //    else
        //    {
        //        return string.Empty;
        //    }
        //}
    }
}
